﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using MasterDetailTemplate.Models;
using SQLite;

namespace MasterDetailTemplate.Services.impl
{
    public class DietStorageService : IDietStorageService {
        public const string DietDBName = "dailydiet.db";

        public static readonly string DBPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder
                .LocalApplicationData), DietDBName);

        private IPreferenceStorage _preference;

        private SQLiteAsyncConnection _connection;

        public SQLiteAsyncConnection Connection =>
            _connection ?? (_connection = new SQLiteAsyncConnection(DBPath));

        public async Task InitializeAsync() {
            using (var embeddedResourceStream = 
                Assembly.GetExecutingAssembly().GetManifestResourceStream(DietDBName))
            using (var fileStream = 
                new FileStream(DBPath, FileMode.OpenOrCreate)) {
                if (embeddedResourceStream == null || fileStream == null) {
                    throw new Exception();
                }
                await embeddedResourceStream.CopyToAsync(fileStream);
                _preference.Set(DietStorageConstants.VersionKey, DietStorageConstants.VERSION);
            }
        }

        public bool IsInitialized() =>
            _preference
                .Get(DietStorageConstants.VersionKey,
                    DietStorageConstants.DEFAULTVERSION)
                .Equals(DietStorageConstants.VERSION);

        public async Task<Diet> GetDietAsync(int dietId) =>
            await Connection.Table<Diet>()
                .FirstOrDefaultAsync(p => p.Id == dietId);


        public async Task<List<Diet>> GetDietsAsync(
            Expression<Func<Diet, bool>> @where, int skip, int take) =>
            await Connection.Table<Diet>().Where(where).Skip(skip).Take(take).ToListAsync();

        public async Task CloseConnection() {
            await _connection.CloseAsync();
            _connection = null;
        }


        //*******构造函数
        public DietStorageService(IPreferenceStorage preference) {
            _preference = preference;
        }
    }
}
